package com.haifeng.asms.auth.filter;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.http.HttpStatus;
import com.haifeng.asms.auth.context.AsmsContext;
import com.haifeng.asms.commons.common.Rest;
import com.haifeng.asms.commons.utils.JsonUtil;
import com.haifeng.asms.commons.utils.MessageUtil;
import com.haifeng.asms.dao.model.dto.PermissionDto;
import com.haifeng.asms.dao.model.dto.UserDto;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Set;

/**
 * <p>
 * Token过滤器
 * </p>
 *
 * @author: Haifeng
 * @date: 2020-06-22
 */
@Slf4j
@Component
@Order(103)
@AllArgsConstructor
public class TokenFilter extends OncePerRequestFilter {

    private final AntPathMatcher antPathMatcher = new AntPathMatcher();
    private final MessageUtil messageUtil;

    /**
     * 校验token权限
     *
     * @param request
     * @param response
     * @param filterChain
     * @throws IOException
     * @throws ServletException
     */
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        response.setContentType("application/json;charset=UTF-8");
        try {
            String uri = request.getRequestURI();

            UserDto userDto = AsmsContext.getUser();
            Set<PermissionDto> permissionDtos = userDto.getPermissionList();
            // 跳过超级管理员
            if (userDto.getSuperAdmin()) {
                filterChain.doFilter(request, response);
                return;
            }
            Boolean hasPermission = false;
            if (CollUtil.isNotEmpty(permissionDtos)) {
                for (PermissionDto permissionDto : permissionDtos) {
                    if (antPathMatcher.match(permissionDto.getPermissionUrl(), uri)) {
                        hasPermission = true;
                        break;
                    }
                }
            }
            if (hasPermission) {
                filterChain.doFilter(request, response);
                return;
            }
            Rest rest = Rest.error(HttpStatus.HTTP_FORBIDDEN, messageUtil.get(HttpStatus.HTTP_FORBIDDEN));
            response.getWriter().write(JsonUtil.toJsonString(rest));
        } catch (Exception e) {
            Rest rest = Rest.error(HttpStatus.HTTP_INTERNAL_ERROR, e.getMessage());
            response.getWriter().write(JsonUtil.toJsonString(rest));
        }
    }
}
